/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ru.staf.NetworkReportGenerator.V2;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.LineNumberReader;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.Set;
import java.util.TreeSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Collection;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Date;
import java.util.GregorianCalendar;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Locale;
import org.jrobin.core.RrdException;
import org.xml.sax.SAXException;

import ru.staf.NetworkReportGenerator.SysUtil;

/**
 *
 * @author aezhov
 */
public class ConfigParser implements Comparator<Switch> {

    public class LoginEntry {
            public String login;
            public String pass;
     }

    HashMap<String, Switch> switches = new HashMap<String, Switch>();
    static Switch rootSwitch = null;
    Pattern ptrn1 = Pattern.compile("^.+\\D(\\d+)$");
    Pattern remPtrn = Pattern.compile("^([^#]*)#.*$");
    public static NmapOutputParser nmap = null;
    public static boolean dontProbeDevices = false;
    String monStatMAC = null;
    String outputFilename = null;
    public static TreeMap<Integer, LoginEntry>  logins =
            new TreeMap<Integer, LoginEntry>();

    public ConfigParser(String configFileName, Date fromDate, Date toDate) 
            throws FileNotFoundException, IOException, ConfigurationException,
                                               RrdException
    {
       
        File configFile = new File(configFileName);
        if (configFile.exists()) {
            LineNumberReader reader =
                    new LineNumberReader(new FileReader(configFile));
            String line = null;
            while ((line = reader.readLine()) != null) {
                Matcher rm = remPtrn.matcher(line);
                if (rm.matches()) {
                    line = rm.group(1);
                }

                line = line.trim();
                int index1 = line.indexOf('.');
                if (index1 < 0) {
                    continue;
                }

                String swName = line.substring(0, index1);
                if (swName.equals("pgsql")) {

                } else if (swName.equals("monitor")) {
                    int index2 = line.indexOf("=");
                    if (index2 < 0)
                        continue;

                    String qName = line.substring(index1 + 1, index2);
                    if (qName.equals("mac")) {
                        String value = line.substring(index2 + 1);
                        if (value == null || value.length() == 0)
                            throw new ConfigurationException("ConfigParser: " +
                                    "MAC address of configuration interface " +
                                    " is not defined");
                        monStatMAC = value;
                        System.out.println("MONITOR STATION MAC == " + monStatMAC);
                    } else if (qName.equals("outprefix")) {
                        String value = line.substring(index2 + 1);
                        if (value == null || value.length() == 0)
                            throw new ConfigurationException("ConfigParser: " +
                                    " output filename prefix is not defined");
                        outputFilename = value;
                        GregorianCalendar cal = new GregorianCalendar();
                        String dateStr = cal.get(cal.DAY_OF_MONTH) + "_" +
                                new Integer(cal.get(cal.MONTH) + 1).toString() + "_" +
                                cal.get(cal.YEAR) + "_" +
                                cal.get(cal.HOUR_OF_DAY) + "_" +
                                cal.get(cal.MINUTE);
                        outputFilename += "_" + dateStr + ".xls";
                        System.out.println("ConfigParser: OUTPUT FILENAME IS " +
                                outputFilename);
                    }
                }  else if (swName.equals("nmap")) {
                    int index2 = line.indexOf('=');
                    if (index2 < 0)
                        continue;

                    String qName = line.substring(index1 + 1, index2);
                    if (qName.equals("output")) {
                        String value = line.substring(index2 + 1);
                        System.out.println("ConfigParser: NMAP OUTPUT DIR IS " +
                                value);

                        try {
                            nmap = new NmapOutputParser(value);
                        } catch (org.xml.sax.SAXException exc) {
                            System.out.println("ConfigParser: NMAP Parser can't" +
                                    " be instantiated " + exc);
                        }
                    }
                } else if (swName.equals("device")) {
                    int index2 = line.indexOf('=');
                    if (index2 < 0)
                        continue;

                    String qName = line.substring(index1 + 1, index2);
                    String value = line.substring(index2 + 1);
                    String[] parts = qName.split("\\.");
                    if (parts[0].equals("probe")) {
                        Integer flag = new Integer(value);
                        if (flag.intValue() == 0) {
                            dontProbeDevices = true;
                        }
                    } else if (parts[0].equals("login")) {
                        String numStr = parts[1];
                        Integer num = new Integer(numStr);
                        LoginEntry le = logins.get(num);
                        if (le == null) {
                            le = new LoginEntry();
                            logins.put(num, le);
                        }
                        le.login = value;
                    } else if (parts[0].equals("pass")) {
                        String numStr = parts[1];
                        Integer num = new Integer(numStr);
                        LoginEntry le = logins.get(num);
                        if (le == null) {
                            le = new LoginEntry();
                            logins.put(num, le);
                        }
                        le.pass = value;
                    }
                } else {
                    int index2 = line.indexOf('=');
                    if (index2 < 0) {
                        continue;
                    }

                    String qName = line.substring(index1 + 1, index2);
                    String value = line.substring(index2 + 1);

                    Switch sw = switches.get(swName);
                    if (sw == null) {
                        sw = new Switch(swName, fromDate, toDate);
                        switches.put(swName, sw);
                    }
                    sw.addConfigProperty(qName, value);
                }
            }

            for (Integer num : logins.keySet()) {
                LoginEntry le = logins.get(num);
                System.out.println("++++++ AUTH ENTRY #" + num +
                        " login == " + le.login + " , pass == " + le.pass);
            }

            Collection<Switch> swSet = switches.values();
            Iterator<Switch> swIt = swSet.iterator();
            while (swIt.hasNext()) {
                Switch sw = swIt.next();
                System.out.println("ConfigParser. Commiting config for " +
                        sw.getName());
                if (sw.commitConfiguration(monStatMAC.toUpperCase()))
                    rootSwitch = sw;
                SysUtil.usedMemory("after " + sw.name + " created");
            }

            for (Switch sw : swSet) {
                sw.calculatePathes(switches.values());
            }

            for (Switch sw : swSet) {
                sw.recalculatePathes();
            }

            for (String port : switches.keySet()) {
                Switch sw = switches.get(port);
                sw.setReverseLinks();
            }

            HashMap<String, Switch> autoSwitches = new HashMap<String, Switch>();
            for (Switch sw: swSet) {
                autoSwitches.putAll(sw.constructConnections());
            }
            switches.putAll(autoSwitches);
            
        } else
            throw new ConfigurationException(" config file " + configFileName +
                    " not found");
    }


    public Set<Switch> getSwitchList() {
       Set<Switch> swSet = new TreeSet<Switch>(this);
       swSet.addAll(switches.values());
       return swSet;
    }


    public Switch getRoot() {
        return rootSwitch;
    }

    public NmapOutputParser getNmap() {
        return nmap;
    }

    public String getOutputFilename() {
        return outputFilename;
    }

    // Comparator implementation
    public int compare(Switch sw1, Switch sw2) {
        Matcher m1 = ptrn1.matcher(sw1.getName());
        Matcher m2 = ptrn1.matcher(sw2.getName());

        if (m1.matches() && m2.matches()) {
            if (sw1 instanceof AutoSwitch && !(sw2 instanceof AutoSwitch))
                return 1;

            if (sw2 instanceof AutoSwitch && !(sw1 instanceof AutoSwitch))
                return -1;

            int n1 = new Integer(m1.group(1)).intValue();
            int n2 = new Integer(m2.group(1)).intValue();
            return (n1 - n2);
        } else
            return sw1.getName().compareTo(sw2.getName());
    }
 }
